import { decrypt, encrypt } from '@utils/crypto'

/**
 * 存储系统
 * @author 木人心
 * @version 1.1.1
 */
class LocalStorage {
  dataset = new Map<string, string>()
  getItem (key: string) {
    return this.dataset.get(key)
  }

  setItem (key: string, value: string) {
    this.dataset.set(key, value)
  }

  clear () {
    this.dataset.clear()
  }

  removeItem (key: string) {
    this.dataset.delete(key)
  }
}

class SessionStorage extends LocalStorage {}

export class storage {
  static localStorage: Storage | LocalStorage = null
  static sessionStorage: Storage | SessionStorage = null
  static init () {
    // 解决在iframe中无痕模式无法使用localStorage和sessionStorage问题
    try {
      this.localStorage = window.localStorage
    } catch (e) {
      this.localStorage = new LocalStorage()
    }
    try {
      this.sessionStorage = window.sessionStorage
    } catch (e) {
      this.sessionStorage = new SessionStorage()
    }
  }

  static local = {
    /**
     * 获取localStorage的值 - 解密
     * @param key
     */
    get (key: string): any {
      const str = storage.localStorage.getItem(key)
      if (str) {
        return JSON.parse(decrypt(str))
      }
    },
    /**
     * 设置localStorage的值 - 加密
     * @param key
     * @param value
     */
    set (key: string, value: any): void {
      storage.localStorage.setItem(key, encrypt(JSON.stringify(value)))
    },
    remove: (key: string) => { storage.localStorage.removeItem(key) },
    clear: () => { storage.localStorage.clear() }
  }

  static session = {
    /**
     * 获取sessionStorage的值 - 解密
     * @param key
     */
    get (key: string): any {
      const str = storage.sessionStorage.getItem(key)
      if (str) {
        return JSON.parse(decrypt(str))
      }
    },
    /**
     * 设置sessionStorage的值 - 加密
     * @param key
     * @param value
     */
    set (key: string, value: any): void {
      storage.sessionStorage.setItem(key, encrypt(JSON.stringify(value)))
    },
    remove: (key: string) => { storage.sessionStorage.removeItem(key) },
    clear: () => { storage.sessionStorage.clear() }
  }

  static cookie = {
    /**
     * 获取cookie
     * @param key
     */
    get (key: string): string {
      const str = this.getAll()[key]
      return str ? decrypt(str) : undefined
    },
    /**
     * 设置cookie
     * @param key
     * @param value
     * @param expires 日期字符串|日期对象|天数
     * @param path
     */
    set (key: string, value: string, expires?: string | Date | number, path = '/'): void {
      let cookieStr = `${key}=${encrypt(value)};path=${path}`
      if (expires) {
        let date: Date = new Date()
        if (typeof expires === 'number') {
          date.setTime(date.getTime() + expires * 86400000)
        } else {
          date = new Date(expires)
        }
        cookieStr += ';expires=' + date.toUTCString()
      }
      document.cookie = cookieStr
    },
    /**
     * 获取所有cookie
     */
    getAll (): Record<string, string> {
      const cookieStr = document.cookie
      const cookieArr = cookieStr.split(';')
      const cookieObj: Record<string, string> = {}
      cookieArr.forEach(item => {
        const m = item.split('=')
        cookieObj[m[0].trim()] = m[1]
      })
      return cookieObj
    },
    /**
     * 删除cookie
     * @param key
     */
    remove (key: string): void {
      this.set(key, '', -1)
    }
  }
}

storage.init()
